import * as THREE from 'three';
const model = new THREE.Group();
const lineGroup = new THREE.Group();//边界线组
const meshGroup = new THREE.Group();//区域填充组
const pillarMeshGroup = new THREE.Group();//柱子组
// const size = 1.2;
const mapHeight = 1
const loader = new THREE.FileLoader();
loader.setResponseType("json")
// 解析gdp文件数据
loader.load('',()=>{ 
})
loader.load('/china.json',(data)=>{
    data.features.forEach((area)=>{
        // coordinates数据分为单组和多组，将单组的封装为多组
        if(area.geometry.type === 'Polygon'){
            area.geometry.coordinates = [area.geometry.coordinates]
        }
        lineGroup.add(moreLine(area.geometry.coordinates,mapHeight)) 
        meshGroup.add(shapeMesh(area.geometry.coordinates,area.properties.name,area.properties.center))
    })
    // lineGroup.position.z += mapHeight + 0.01 *mapHeight
    const pathLine = curveLine()
    model.add(lineGroup,meshGroup,pillarMeshGroup,...pathLine)
})

// 批量产生轮廓线
const moreLine = (coordinates,gdpvalue)=>{
    const groupLine = new THREE.Group();
    coordinates.forEach(polygon => {
        var pointArr = []
        polygon[0].forEach((elem)=>{
            pointArr.push(elem[0],elem[1],0)
        })
        groupLine.add(oneLine(pointArr))
    });
    groupLine.position.z += gdpvalue+ 0.001*gdpvalue
    return groupLine
}
// 产生一条轮廓线
const oneLine = (pointArr)=>{
    const geometry = new THREE.BufferGeometry();
    const vertices = new Float32Array(pointArr);
    geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
    const material = new THREE.LineBasicMaterial({
        color: 0x006666
    });
    const line = new THREE.LineLoop(geometry,material);
    return line;
}
// 产生多边形面
const shapeMesh = (coordinates,name,lngLat)=>{
    var heartShape = [];//轮廓形状Shape集合
    coordinates.forEach(polygon => {
        var pointArr = []
        polygon[0].forEach((elem)=>{
            pointArr.push(new THREE.Vector3(elem[0],elem[1],0))
        })
        const shape = new THREE.Shape(pointArr);
        heartShape.push(shape)
    });
    var material = new THREE.MeshLambertMaterial({
        color: 0x004444,
        // side: THREE.DoubleSide, //两面可见
    }); //材质对象
    var geometry = new THREE.ExtrudeGeometry( heartShape ,{
        depth: mapHeight, //拉伸长度
        bevelEnabled: false //无倒角
    });
    var mesh =  new THREE.Mesh( geometry, material )
    mesh.lngLat = lngLat
    mesh.name = name
    return mesh
}
// 产生一条曲线轨迹
const curveLine = () =>{
    // 84.9023, 41.748
    const arr = [
        new THREE.Vector3(113.4668, 33.8818, mapHeight + 0.1),
        new THREE.Vector3(98.5, 38, 5),
        new THREE.Vector3(84.9023, 41.748, mapHeight + 0.1)
    ]
    // 三维样条曲线
    const curve = new THREE.CatmullRomCurve3(arr);
    //曲线上获取点
    const pointsArr = curve.getPoints(100); 
    const geometry = new THREE.BufferGeometry();
    //读取坐标数据赋值给几何体顶点
    geometry.setFromPoints(pointsArr); 
    // 线材质
    const material = new THREE.LineBasicMaterial({
    color: 0x006666
    });
    // 线模型
    const line = new THREE.Line(geometry, material);
    // 从轨迹线上去10个点，从第20个开始取，生成一个飞线段
    var index = 20
    var num = 10
    var flyLineArr = pointsArr.slice(index,index+num)
    const geometry2 = new THREE.BufferGeometry();
    // 将20个点形成一个新的曲线，在上面取更多的点
    const curve2 = new THREE.CatmullRomCurve3(flyLineArr);
    //曲线上获取点
    const pointsArr2 = curve2.getPoints(100); 
    // 将100个点设置给geometry2
    geometry2.setFromPoints(pointsArr2);
    
    const colorArr = []
    for(let i = 0;i < pointsArr2.length;i++){
        var color1 = new THREE.Color(0x006666); //轨迹线颜色 青色
        var color2 = new THREE.Color(0xffff00); //黄色
        var color = color1.lerp(color2, i / pointsArr2.length)
        colorArr.push(color.r, color.g, color.b);
    }
    // 设置几何体顶点颜色数据
    geometry2.attributes.color = new THREE.BufferAttribute(new Float32Array(colorArr), 3);
    const material2 = new THREE.PointsMaterial({
        // color: 0xffffff,
        vertexColors: true,
        size: 5.0, //点大小
        });
        // 修改点材质的着色器源码(注意：不同版本细节可能会稍微会有区别，不过整体思路是一样的)
    // 每个顶点对应一个百分比数据attributes.percent 用于控制点的渲染大小
    var percentArr = []; //attributes.percent的数据
    for (var i = 0; i < pointsArr2.length; i++) {
        percentArr.push(i / pointsArr2.length);
    }
    var percentAttribue = new THREE.BufferAttribute(new Float32Array(percentArr), 1);
    geometry2.attributes.percent = percentAttribue;
    material2.onBeforeCompile = function (shader) {
        // 顶点着色器中声明一个attribute变量:百分比
        shader.vertexShader = shader.vertexShader.replace(
            'void main() {',
            [
                'attribute float percent;', //顶点大小百分比变量，控制点渲染大小
                'void main() {',
            ].join('\n') // .join()把数组元素合成字符串
        );
        // 调整点渲染大小计算方式
        shader.vertexShader = shader.vertexShader.replace(
            'gl_PointSize = size;',
            [
                'gl_PointSize = percent * size;',
            ].join('\n') // .join()把数组元素合成字符串
        );
    };
    // 飞线
    function render (){
        if(index+num >= pointsArr.length){
            index = 0
        }
        index++
        const points2 = pointsArr.slice(index,index+num)
        var curve3 = new THREE.CatmullRomCurve3(points2);
        var newPoints2 = curve3.getPoints(100); //获取更多的点数
        geometry2.setFromPoints(newPoints2);
        requestAnimationFrame(render);
    }
    render()
    // 线模型
    const flyLine = new THREE.Points(geometry2, material2);
    return [line,flyLine]
}


export {model};